package sk.ownage.p1.featurestore;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

import android.os.Environment;
import android.util.Log;

public class TrackReader {
	private final String TAG="TrackReader";
	private final String rootPath=Environment.getExternalStorageDirectory()+"/featureStore"+"/tracks";
	private final int DIRECTORY_MAX=TrackStore.DIRECTORY_MAX;
	private String trackPath="";
	public final int WRONG_FILE=-1;
	public final int START_FILE=0;
	public final int NAME_READ_DONE=1;
	public final int ACTIVITY_READ_DONE=2;
	public final int TIMESTAMP_READ_DONE=3;
	public final int DESCRIPTION_READ_DONE=4;
	public final int DESCRIPTION_EMPTY_READ_DONE=41;
	public final int NEW_TRACK_FLAG_READ_DONE=5;
	public final int NEW_SEGMENT_FLAG_READ_DONE=6;
	public final int NEW_WAYPOINT_FLAG_READ_DONE=7;
	public final int WAYPOINT_LATITUDE_READ_DONE=71;
	public final int WAYPOINT_LONGITUDE_READ_DONE=72;
	public final int WAYPOINT_ALTITUDE_READ_DONE=73;
	public final int WAYPOINT_TIMESTAMP_READ_DONE=74;
	public final int END_SEGMENT_FLAG_READ_DONE=61;
	public final int END_TRACK_FLAG_READ_DONE=51;
	public final int END_FILE_FLAG_READ_DONE=8;
	public final int FILE_CLOSED_SUCCESSFUL=9;
	private int readerState=0;
	private FileInputStream fis;
	private ObjectInputStream is;
	
	
	
	public TrackReader(int trackId){
		this(trackId, "");
	}
	

	public TrackReader(int trackId, String trackRootPath){
		int folderId=trackId/DIRECTORY_MAX;
		int fileId=trackId%DIRECTORY_MAX;
		String folderPath=(((folderId/100)>0)?"":"0")+(((folderId/10)>0)?"":"0")+folderId;
		String filePath=(((fileId/100)>0)?"":"0")+(((fileId/10)>0)?"":"0")+fileId;
		trackPath=((!trackRootPath.equals(""))?trackRootPath:rootPath)+"/"+folderPath+"/"+filePath+".bin";
		Log.d(TAG,">>prve>>"+trackRootPath+"/"+folderPath+"/"+filePath+".bin");
		Log.d(TAG,">>druhe>>"+rootPath+"/"+folderPath+"/"+filePath+".bin");
		File trackFile=new File(trackPath);
		if(trackFile.exists()){
			try {
				fis = new FileInputStream(trackFile);
				is = new ObjectInputStream(new BufferedInputStream(fis));
					readerState=START_FILE;
			} catch (Exception e) {
				Log.d(TAG, e.toString());
				e.printStackTrace();
			}
		}
	}
	
	public String readName() throws Exception{
		String result="";
		if(readerState==START_FILE){
			try {
				if(is.readByte()==1){
					result=is.readUTF();
					readerState=NAME_READ_DONE;
				}
				else{
					readerState=WRONG_FILE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		} 
		else{
			throw new Exception("Cannot read Name at this state!");
		}
	}
	
	public String readActivity() throws Exception{
		String result="";
		if(readerState==NAME_READ_DONE){
			try {
				if(is.readByte()==1){
					result=is.readUTF();
					readerState=ACTIVITY_READ_DONE;
				}
				else{
					readerState=WRONG_FILE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		} 
		else{
			throw new Exception("Cannot read Activity name at this state!");
		}
	}
	
	public long readTimestamp() throws Exception{
		long result=0;
		if(readerState==ACTIVITY_READ_DONE){
			try {
				if(is.readByte()==1){
					result=is.readLong();
					readerState=TIMESTAMP_READ_DONE;
				}
				else{
					readerState=WRONG_FILE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		} 
		else{
			throw new Exception("Cannot read Timestamp at this state!");
		}
	}
	
	public String readDescription() throws Exception{
		String result="";
		if(readerState==TIMESTAMP_READ_DONE){
			try {
				byte nextByte=is.readByte();
				if(nextByte==1){
					result=is.readUTF();
					readerState=DESCRIPTION_READ_DONE;
				}
				else if(nextByte==0){
					readerState=DESCRIPTION_EMPTY_READ_DONE;//empty desc
				}
				else{
					readerState=WRONG_FILE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}else{
			throw new Exception("Cannot read Description at this state!");
		}
	}
	
	public boolean hasTrack() throws Exception{
		boolean result=false;
		if(readerState==DESCRIPTION_READ_DONE || readerState==DESCRIPTION_EMPTY_READ_DONE || readerState==END_TRACK_FLAG_READ_DONE){
			try {
				result=(is.readByte()==1);
				if(result){
					readerState=NEW_TRACK_FLAG_READ_DONE;
				}
				else{
					readerState=END_FILE_FLAG_READ_DONE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read NewTrack flag at this state!");
		}
	}
	
	public boolean hasSegment() throws Exception{
		boolean result=false;
		if(readerState==NEW_TRACK_FLAG_READ_DONE || readerState==END_SEGMENT_FLAG_READ_DONE){
			try {
				result=(is.readByte()==1);
				if(result){
					readerState=NEW_SEGMENT_FLAG_READ_DONE;
				}
				else{
					readerState=END_TRACK_FLAG_READ_DONE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read NewSegment flag at this state!");
		}
	}
	
	public boolean hasWaypoint() throws Exception{
		boolean result=false;
		if(readerState==NEW_SEGMENT_FLAG_READ_DONE || readerState==WAYPOINT_TIMESTAMP_READ_DONE){
			try {
				result=(is.readByte()==1);
				if(result){
					readerState=NEW_WAYPOINT_FLAG_READ_DONE;
				}
				else{
					readerState=END_SEGMENT_FLAG_READ_DONE;
				}
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read New Waypoint flag at this state!");
		}
	}
	
	public double readWaypointLatitude() throws Exception{
		double result=0;
		if(readerState==NEW_WAYPOINT_FLAG_READ_DONE){
			try {
				result=is.readDouble();
					readerState=WAYPOINT_LATITUDE_READ_DONE;
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read waypoint latitude at this state!");
		}
	}
	
	public double readWaypointLongitude() throws Exception{
		double result=0;
		if(readerState==WAYPOINT_LATITUDE_READ_DONE){
			try {
				result=is.readDouble();
					readerState=WAYPOINT_LONGITUDE_READ_DONE;
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read waypoint longitude at this state!");
		}
	}
	
	public double readWaypointAltitude() throws Exception{
		double result=0;
		if(readerState==WAYPOINT_LONGITUDE_READ_DONE){
			try {
				result=is.readDouble();
					readerState=WAYPOINT_ALTITUDE_READ_DONE;
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read waypoint altitude at this state!");
		}
	}
	
	public long readWaypointTimestamp() throws Exception{
		long result=0;
		if(readerState==WAYPOINT_ALTITUDE_READ_DONE){
			try {
				result=is.readLong();
					readerState=WAYPOINT_TIMESTAMP_READ_DONE;
			} catch (Exception e) {
				Log.d(TAG,e.toString());
				e.printStackTrace();
			}
			return result;
		}
		else{
			throw new Exception("Cannot read waypoint timestamp at this state!");
		}
	}
		
	public void stopReader(){
		try {
			is.close();
		} catch (IOException e) {
			Log.d(TAG, e.toString());
			e.printStackTrace();
		}
	}
	
	public void resetReader(){
		try {
			is.close();
			is = new ObjectInputStream(new BufferedInputStream(fis));
			readerState=START_FILE;
		} catch (IOException e) {
			Log.d(TAG, e.toString());
			e.printStackTrace();
		}
	}
	
	public int getReaderState(){
		return readerState;
	}

}
